package com.example.aircraftwar.codes.application.game;

import static com.example.aircraftwar.codes.activity.GameActivity.game;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.Typeface;
import android.widget.FrameLayout;
import android.widget.TextView;

import com.example.aircraftwar.codes.activity.GameActivity;
import com.example.aircraftwar.codes.activity.RankActivity;
import com.example.aircraftwar.codes.aircraft.AbstractAircraft;
import com.example.aircraftwar.codes.aircraft.BaseEnemyAircraft;
import com.example.aircraftwar.codes.aircraft.BossEnemy;
import com.example.aircraftwar.codes.aircraft.HeroAircraft;
import com.example.aircraftwar.codes.aircraft.Observer;
import com.example.aircraftwar.codes.basic.AbstractFlyingObject;
import com.example.aircraftwar.codes.basic.GameBackground;
import com.example.aircraftwar.codes.bullet.BaseBullet;
import com.example.aircraftwar.codes.bullet.EnemyBullet;
import com.example.aircraftwar.codes.factory.EliteEnemyFactory;
import com.example.aircraftwar.codes.factory.EnemyAircraftFactory;
import com.example.aircraftwar.codes.factory.MobEnemyFactory;
import com.example.aircraftwar.codes.application.music.MusicService;
import com.example.aircraftwar.codes.prop.AbstractProp;
import com.example.aircraftwar.codes.prop.BloodProp;
import com.example.aircraftwar.codes.prop.BombProp;
import com.example.aircraftwar.codes.prop.BulletProp;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public abstract class Game extends FrameLayout {
    protected Activity context;

    private GameBackground background;

    private int backGroundTop = 0;

    /**
     * Scheduled 线程池，用于任务调度
     */
    private final ScheduledExecutorService executorService;

    /**
     * 时间间隔(ms)，控制刷新频率
     */
    private int timeInterval = 40;

    private HeroAircraft heroAircraft;

    protected final List<BaseEnemyAircraft> enemyAircrafts;
    private final List<BaseBullet> heroBullets;
    private final List<BaseBullet> enemyBullets;
    private final List<AbstractProp> randomProps;
    protected EnemyAircraftFactory enemyAircraftFactory;

    private int enemyMaxNumber = 8;

    private boolean gameOverFlag = false;
    protected int score = 0;
    protected int time = 0;

    protected int bossSign = 1;
    protected int bossSHoot = 0;
    protected boolean bossFlag = false;
    private TextView scoreAndHp;
    /**
     * 周期（ms)
     * 指示子弹的发射、敌机的产生频率
     */
    private int cycleDuration = 500;
    private int cycleTime = 0;

    protected double eliteGenerationRate = 0.25;
    protected double attributeRate = 1.0;
    protected double propReductionRate = 1.0;
    protected int bossHpAdd = 0;

    protected  boolean videoOpen;
    protected Intent intent_bgm;
    protected Intent intent_boss;

    @SuppressLint("ClickableViewAccessibility")
    public Game(Activity context, Bitmap background, boolean videoOpen) {
        super(context);
        this.context = context;
        this.background = new GameBackground(context, background);
        this.videoOpen = videoOpen;


        heroAircraft = HeroAircraft.getHeroAircraft(context);
        heroAircraft.setOnTouchListener((v, event) -> {
            heroAircraft.setLocation(event.getX(), event.getY());
            return true;
        });
        scoreAndHp = new TextView(context);
        scoreAndHp.setTextColor(Color.GREEN);
        scoreAndHp.setTypeface(Typeface.SANS_SERIF);
        scoreAndHp.setTextSize(30);

        this.addView(this.background);
        this.addView(heroAircraft);
        this.addView(scoreAndHp);

        enemyAircrafts = new LinkedList<>();
        heroBullets = new LinkedList<>();
        enemyBullets = new LinkedList<>();
        randomProps = new LinkedList<>();

        intent_bgm = new Intent(context, MusicService.class);
        intent_bgm.putExtra("videoName", "bgm");
        intent_boss = new Intent(context, MusicService.class);
        intent_boss.putExtra("videoName", "boss");

        intent_boss.putExtra("videoOpen", false);
        context.startService(intent_boss);
        intent_bgm.putExtra("videoOpen", this.videoOpen);
        context.startService(intent_bgm);

        //Scheduled 线程池，用于定时任务调度
        executorService = new ScheduledThreadPoolExecutor(1);

    }

    /**
     * 游戏启动入口，执行游戏逻辑
     */
    public void action() {
        // 定时任务：绘制、对象产生、碰撞判定、击毁及结束判定
        Runnable task = () -> {

            time += timeInterval;
            System.out.println(time);
            //产生敌机
            if (timeCountAndNewCycleJudge()){
                enemyGeneration();
                bossGeneration();
                shootAction();
            }

            //更新控制难度的参数
            difficultyControl();

            // 子弹移动
            bulletsMoveAction();

            // 飞机移动
            aircraftsMoveAction();

            //道具移动
            propsMoveAction();

            // 撞击检测
            crashCheckAction();

            // 后处理
            postProcessAction();

            //每个时刻重绘界面
            paint();

            // 游戏结束检查
            gameOver();

        };

        /**
         * 以固定延迟时间进行执行
         * 本次任务执行完成后，需要延迟设定的延迟时间，才会执行新的任务
         */
        executorService.scheduleWithFixedDelay(task, timeInterval, timeInterval, TimeUnit.MILLISECONDS);
    }

    //***********************
    //      Action 各部分
    //***********************

    public abstract void difficultyControl();
    //更新与难度控制有关的属性

    private void enemyGeneration(){

        // 新敌机产生
        if (enemyAircrafts.size() < enemyMaxNumber){
            double enemyRandom = Math.random();
            if (enemyRandom < eliteGenerationRate) {
                enemyAircraftFactory = new EliteEnemyFactory();
            } else {
                enemyAircraftFactory = new MobEnemyFactory();
            }
            BaseEnemyAircraft enemyAircraft = enemyAircraftFactory.createEnemyAircraft(context);
            enemyAircrafts.add(enemyAircraft);
            context.runOnUiThread(() -> this.addView(enemyAircraft));
        }
    }

    public abstract void bossGeneration();
        //控制Boss机的产生


    public void gameOver(){
        if (heroAircraft.getHp() <= 0) {
            // 游戏结束
            executorService.shutdown();
            gameOverFlag = true;

            GameActivity.myBinder.playGameOver();

            intent_boss.putExtra("videoOpen", false);
            context.startService(intent_boss);
            intent_bgm.putExtra("videoOpen", false);
            context.startService(intent_bgm);

            Intent intent = new Intent(context,RankActivity.class);
            if(game instanceof SimpleGame){
                intent.putExtra("difficulty","simple");
            }
            if(game instanceof NormalGame){
                intent.putExtra("difficulty","normal");
            }
            if(game instanceof DifficultGame){
                intent.putExtra("difficulty","difficult");
            }
            intent.putExtra("score",score);
            Calendar calendar = Calendar.getInstance();
            SimpleDateFormat formatter = new SimpleDateFormat("MM-dd HH:mm");
            intent.putExtra("time", formatter.format(calendar.getTime()));
            context.startActivity(intent);
        }
    }

    private boolean timeCountAndNewCycleJudge() {
        cycleTime += timeInterval;
        if (cycleTime >= cycleDuration && cycleTime - timeInterval < cycleTime) {
            // 跨越到新的周期
            cycleTime %= cycleDuration;
            return true;
        } else {
            return false;
        }
    }

    private void shootAction() {
        //敌机射击
        for (BaseEnemyAircraft enemyAircraft : enemyAircrafts) {
            if(enemyAircraft instanceof BossEnemy){
                if(bossSHoot==3){
                    for (BaseBullet bullet : enemyAircraft.shoot()) {
                        enemyBullets.add(bullet);
                        context.runOnUiThread(() -> this.addView(bullet));
                    }
                    bossSHoot = 0;
                }else{
                    bossSHoot ++;
                }

            }else{
                for (BaseBullet bullet : enemyAircraft.shoot()) {
                    enemyBullets.add(bullet);
                    context.runOnUiThread(() -> this.addView(bullet));
                }
            }

        }

        // 英雄射击
        for (BaseBullet bullet : heroAircraft.shoot()) {
            heroBullets.add(bullet);
            context.runOnUiThread(() -> this.addView(bullet));
        }
    }

    private void bulletsMoveAction() {
        for (BaseBullet bullet : heroBullets) {
            bullet.forward();
        }
        for (BaseBullet bullet : enemyBullets) {
            bullet.forward();
        }
    }

    private void aircraftsMoveAction() {
        for (AbstractAircraft enemyAircraft : enemyAircrafts) {
            enemyAircraft.forward();
        }
    }

    private void propsMoveAction() {
        for (AbstractProp prop : randomProps) {
            prop.forward();
        }
    }

    /**
     * 碰撞检测：
     * 1. 敌机攻击英雄
     * 2. 英雄攻击/撞击敌机
     * 3. 英雄获得补给
     */
    private void crashCheckAction() {
        for(BaseBullet bullet : enemyBullets) {
            if (bullet.notValid()) {
                continue;
            }
            if (heroAircraft.crash(bullet)) {
                // 英雄机撞击到敌机子弹
                // 英雄损失一定生命值
                heroAircraft.decreaseHp(bullet.getPower());
                bullet.vanish();
            }
        }

        for (BaseEnemyAircraft enemyAircraft : enemyAircrafts) {
            // 英雄子弹攻击敌机
            for (BaseBullet bullet : heroBullets) {
                if (bullet.notValid()) {
                    continue;
                }
                if (enemyAircraft.notValid()) {
                    // 已被其他子弹击毁的敌机，不再检测
                    // 避免多个子弹重复击毁同一敌机的判定
                    continue;
                }
                if (enemyAircraft.crash(bullet)) {
                    // 敌机撞击到英雄机子弹
                    // 敌机损失一定生命值
                    GameActivity.myBinder.playBullet();
                    enemyAircraft.decreaseHp(bullet.getPower());
                    bullet.vanish();
                    if (enemyAircraft.notValid()) {
                        if(enemyAircraft instanceof BossEnemy){
                            intent_boss.putExtra("videoOpen", false);
                            context.startService(intent_boss);
                            intent_bgm.putExtra("videoOpen", videoOpen);
                            context.startService(intent_bgm);
                        }
                        score = enemyAircraft.getScoreAdd(score);
                        /*if(score==150){
                            heroAircraft = HeroAircraft2.getHeroAircraft(context,heroAircraft.getLocationX(),heroAircraft.getLocationY());
                            heroAircraft.setOnTouchListener((v, event) -> {
                                heroAircraft.setLocation(event.getX(), event.getY());
                                return true;
                            });
                        }*/
                        List<AbstractProp> newPropList = enemyAircraft.produceProp();
                        for(AbstractProp newProp : newPropList){
                            context.runOnUiThread(() -> this.addView(newProp));
                            randomProps.add(newProp);
                        }
                    }
                }
            }
            // 英雄机 与 敌机 相撞，均损毁
            if (enemyAircraft.crash(heroAircraft) || heroAircraft.crash(enemyAircraft)) {
                enemyAircraft.vanish();
                heroAircraft.decreaseHp(Integer.MAX_VALUE);
            }
        }
        // 我方获得道具，道具生效
        for (AbstractProp prop : randomProps) {
            if (prop.notValid()) {
                continue;
            }
            if (prop.crash(heroAircraft)) {
                if(prop instanceof BloodProp){
                    GameActivity.myBinder.playSupply();
                 }
                if(prop instanceof BulletProp){
                    GameActivity.myBinder.playSupply();
                }
                if (prop instanceof BombProp)
                {
                    GameActivity.myBinder.playBomb();
                    for(BaseEnemyAircraft enemyAircraft:enemyAircrafts){
                        ((BombProp)prop).addObserver((Observer) enemyAircraft);
                        score = enemyAircraft.getScoreAdd(score);
                    }
                    for(BaseBullet bullet: enemyBullets){
                        ((BombProp)prop).addObserver((Observer) bullet);
                    }
                }
                prop.propAct();
                prop.vanish();
            }
        }
    }

    /**
     * 后处理：
     * 1. 删除无效的子弹
     * 2. 删除无效的敌机
     * 3. 检查英雄机生存
     * 4. 删除无效的道具
     * 无效的原因可能是撞击或者飞出边界
     */
    private void postProcessAction() {
        for (int i = 0; i < enemyBullets.size(); i++) {
            BaseBullet enemyBullet = enemyBullets.get(i);
            if (enemyBullet.notValid()) {
                context.runOnUiThread(() -> this.removeView(enemyBullet));
                enemyBullets.remove(i--);
            }
        }
        for (int i = 0; i < heroBullets.size(); i++) {
            BaseBullet heroBullet = heroBullets.get(i);
            if (heroBullet.notValid()) {
                context.runOnUiThread(() -> this.removeView(heroBullet));
                heroBullets.remove(i--);
            }
        }
        for (int i = 0; i < enemyAircrafts.size(); i++) {
            AbstractAircraft enemy = enemyAircrafts.get(i);
            if (enemy.notValid()) {
                context.runOnUiThread(() -> this.removeView(enemy));
                enemyAircrafts.remove(i--);
            }
        }
        int i = 0;
        while(i < randomProps.size()) {
            AbstractProp prop = randomProps.get(i);
            if (prop.notValid()) {
                context.runOnUiThread(() -> this.removeView(prop));
                randomProps.remove(i--);
            }
            i++;
        }
    }


    //***********************
    //      Paint 各部分
    //***********************

    /**
     * 重写paint方法
     * 通过重复调用paint方法，实现游戏动画
     */
    public void paint() {

        // 绘制背景,图片滚动
        background.setBackGroundTop(backGroundTop);
        context.runOnUiThread(background::invalidate);
        this.backGroundTop += 1;
        if (this.backGroundTop == GameActivity.WINDOW_HEIGHT) {
            this.backGroundTop = 0;
        }

        // 先绘制子弹，后绘制飞机
        // 这样子弹显示在飞机的下层
        paintScoreAndLife();
        paintImageWithPositionRevised(randomProps);

        paintImageWithPositionRevised(enemyBullets);
        paintImageWithPositionRevised(heroBullets);

        paintImageWithPositionRevised(enemyAircrafts);
        context.runOnUiThread(heroAircraft::invalidate);

        //绘制得分和生命值


    }

    private void paintImageWithPositionRevised(List<? extends AbstractFlyingObject> objects) {
        if (objects.size() == 0) {
            return;
        }

        for (AbstractFlyingObject object : objects) {
            context.runOnUiThread(object::invalidate);
        }
    }

    private void paintScoreAndLife() {
        context.runOnUiThread(()-> scoreAndHp.setText("SCORE : " + this.score + '\n' + "LIFE : " + this.heroAircraft.getHp()));
    }

    public final double getAttributeRate() {
        return attributeRate;
    }

    public final double getPropReductionRate(){
        return propReductionRate;
    }

    public final int getBossHpAdd(){
        return bossHpAdd;
    }
}

